home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / fileutil / fileutils-3.16.tar.gz / fileutils-3.16.tar / fileutils-3.16 / lib / euidaccess.c < prev    next >
C/C++ Source or Header  |  1996-07-14  |  4KB  |  183 lines

  1. /* euidaccess -- check if effective user id can access file
  2.    Copyright (C) 1990, 1991, 1995 Free Software Foundation, Inc.
  3.  
  4. This file is part of the GNU C Library.
  5.  
  6. The GNU C Library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Library General Public License as
  8. published by the Free Software Foundation; either version 2 of the
  9. License, or (at your option) any later version.
  10.  
  11. The GNU C Library is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. Library General Public License for more details.
  15.  
  16. You should have received a copy of the GNU Library General Public
  17. License along with the GNU C Library; see the file COPYING.LIB.  If
  18. not, write to the Free Software Foundation, Inc., 59 Temple Place -
  19. Suite 330, Boston, MA 02111-1307, USA.  */
  20.  
  21. /* Written by David MacKenzie and Torbjorn Granlund.
  22.    Adapted for GNU C library by Roland McGrath.  */
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. # include <config.h>
  26. #endif
  27.  
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30.  
  31. #ifdef S_IEXEC
  32. # ifndef S_IXUSR
  33. #  define S_IXUSR S_IEXEC
  34. # endif
  35. # ifndef S_IXGRP
  36. #  define S_IXGRP (S_IEXEC >> 3)
  37. # endif
  38. # ifndef S_IXOTH
  39. #  define S_IXOTH (S_IEXEC >> 6)
  40. # endif
  41. #endif /* S_IEXEC */
  42.  
  43. #if defined (HAVE_UNISTD_H) || defined (_LIBC)
  44. # include <unistd.h>
  45. #endif
  46.  
  47. #ifdef _POSIX_VERSION
  48. # include <limits.h>
  49. # if !defined(NGROUPS_MAX) || NGROUPS_MAX < 1
  50. #  undef NGROUPS_MAX
  51. #  define NGROUPS_MAX sysconf (_SC_NGROUPS_MAX)
  52. # endif /* NGROUPS_MAX */
  53.  
  54. #else /* not _POSIX_VERSION */
  55. uid_t getuid ();
  56. gid_t getgid ();
  57. uid_t geteuid ();
  58. gid_t getegid ();
  59. # include <sys/param.h>
  60. # if !defined(NGROUPS_MAX) && defined(NGROUPS)
  61. #  define NGROUPS_MAX NGROUPS
  62. # endif /* not NGROUPS_MAX and NGROUPS */
  63. #endif /* not POSIX_VERSION */
  64.  
  65. #include <errno.h>
  66. #ifndef errno
  67. extern int errno;
  68. #endif
  69.  
  70. #if defined(EACCES) && !defined(EACCESS)
  71. # define EACCESS EACCES
  72. #endif
  73.  
  74. #ifndef F_OK
  75. # define F_OK 0
  76. # define X_OK 1
  77. # define W_OK 2
  78. # define R_OK 4
  79. #endif
  80.  
  81. #if !defined (S_IROTH) && defined (R_OK)
  82. # define S_IROTH R_OK
  83. #endif
  84.  
  85. #if !defined (S_IWOTH) && defined (W_OK)
  86. # define S_IWOTH W_OK
  87. #endif
  88.  
  89. #if !defined (S_IXOTH) && defined (X_OK)
  90. # define S_IXOTH X_OK
  91. #endif
  92.  
  93. #ifdef _LIBC
  94.  
  95. # define group_member __group_member
  96.  
  97. #else
  98.  
  99. /* The user's real user id. */
  100. static uid_t uid;
  101.  
  102. /* The user's real group id. */
  103. static gid_t gid;
  104.  
  105. /* The user's effective user id. */
  106. static uid_t euid;
  107.  
  108. /* The user's effective group id. */
  109. static gid_t egid;
  110.  
  111. /* Nonzero if UID, GID, EUID, and EGID have valid values. */
  112. static int have_ids = 0;
  113.  
  114. # ifdef HAVE_GETGROUPS
  115. int group_member ();
  116. # else
  117. #  define group_member(gid)    0
  118. # endif
  119.  
  120. #endif
  121.  
  122.  
  123. /* Return 0 if the user has permission of type MODE on file PATH;
  124.    otherwise, return -1 and set `errno' to EACCESS.
  125.    Like access, except that it uses the effective user and group
  126.    id's instead of the real ones, and it does not check for read-only
  127.    filesystem, text busy, etc. */
  128.  
  129. int
  130. euidaccess (path, mode)
  131.      const char *path;
  132.      int mode;
  133. {
  134.   struct stat stats;
  135.   int granted;
  136.  
  137. #ifdef    _LIBC
  138.   uid_t uid = getuid (), euid = geteuid ();
  139.   gid_t gid = getgid (), egid = getegid ();
  140. #else
  141.   if (have_ids == 0)
  142.     {
  143.       have_ids = 1;
  144.       uid = getuid ();
  145.       gid = getgid ();
  146.       euid = geteuid ();
  147.       egid = getegid ();
  148.     }
  149. #endif
  150.  
  151.   if (uid == euid && gid == egid)
  152.     /* If we are not set-uid or set-gid, access does the same.  */
  153.     return access (path, mode);
  154.  
  155.   if (stat (path, &stats))
  156.     return -1;
  157.  
  158.   mode &= (X_OK | W_OK | R_OK);    /* Clear any bogus bits. */
  159. #if R_OK != S_IROTH || W_OK != S_IWOTH || X_OK != S_IXOTH
  160.   ?error Oops, portability assumptions incorrect.
  161. #endif
  162.  
  163.   if (mode == F_OK)
  164.     return 0;            /* The file exists. */
  165.  
  166.   /* The super-user can read and write any file, and execute any file
  167.      that anyone can execute. */
  168.   if (euid == 0 && ((mode & X_OK) == 0
  169.             || (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
  170.     return 0;
  171.  
  172.   if (euid == stats.st_uid)
  173.     granted = (unsigned) (stats.st_mode & (mode << 6)) >> 6;
  174.   else if (egid == stats.st_gid || group_member (stats.st_gid))
  175.     granted = (unsigned) (stats.st_mode & (mode << 3)) >> 3;
  176.   else
  177.     granted = (stats.st_mode & mode);
  178.   if (granted == mode)
  179.     return 0;
  180.   errno = EACCESS;
  181.   return -1;
  182. }
  183.